﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tao.OpenGl;
using PocketEngine.Maths;
using PocketEngine.Images;
using PocketEngine.Engine;
using PocketEngine.Materials;
namespace PocketEngine.Effects
{
    /// <summary>
    /// 
    /// </summary>
    public class pEffectParameter
    {
        public int Handle
        {
            get
            {
                return mHandle;
            }
            set
            {
                mHandle = value;
            }
        }
        public void SetFloat(float v)
        {
            Gl.glUniform1f(mHandle, v);
        }
        public void SetVec2(pVec2 v)
        {
            Gl.glUniform2f(mHandle, v.X, v.Y);
        }
        public void SetVec3(pVec3 v)
        {
            Gl.glUniform3f(mHandle, v.X, v.Y, v.Z);
        }
        public void SetCol(pColor c)
        {
            Gl.glUniform4f(mHandle, c.R, c.G, c.B, c.A);
        }
        public void SetInt(int v)
        {
            Gl.glUniform1i(mHandle, v);
        }
        private int mHandle = 0;
    }

 
    public class pEffect
    {
        public static bool Init()
        {
       
            return true;
        }
        public int Program
        {
            get
            {
                return mProgram;
            }
            set
            {
                mProgram = value;
            }
        }
        private int mProgram = 0;

        /// <summary>
        /// Initializes a new instance of the <see cref="pEffect"/> class.
        /// </summary>
        /// <param name="vertShader">The vert shader.</param>
        /// <param name="pixShader">The pix shader.</param>
        public pEffect(pVertexShader vertShader,pPixelShader pixShader)
        {
            mProgram = Gl.glCreateProgram();
            Console.WriteLine("Program:" + mProgram);
            SetShaders(vertShader, pixShader);
            AttachAndLink();
        }

        /// <summary>
        /// Sets the shaders.
        /// </summary>
        /// <param name="v">The v.</param>
        /// <param name="p">The p.</param>
        public void SetShaders(pVertexShader v, pPixelShader p)
        {
            mVertexShader = v;
            mPixelShader = p;
        }

        public pEffect()
        {
            mVertexShader = null;
            mPixelShader = null;
        }

        /// <summary>
        /// Attaches the and link shaders.
        /// </summary>
        public void AttachAndLink()
        {

            if (mVertexShader != null)
            {
                Gl.glAttachShader(mProgram, mVertexShader.ShaderHandle);
            }
            
            if (mPixelShader != null)
            {
                Gl.glAttachShader(mProgram, mPixelShader.ShaderHandle);
            }
            
            Gl.glLinkProgram(mProgram);

        }

        /// <summary>
        /// Gets the parameter.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public pEffectParameter GetParameter(string name)
        {
            pEffectParameter ret = new pEffectParameter();
            ret.Handle = Gl.glGetUniformLocation(Program, name);
            Console.WriteLine("Handle:"+ret.Handle);
            return ret;
        }

        public virtual void Bind(pMaterial mat)
        {
            Gl.glUseProgram(Program);
        }
        public virtual void Unbind(pMaterial mat)
        {
            Gl.glUseProgram(0);
        }
        public pVertexShader VertexShader
        {
            get
            {
                return mVertexShader;
            }
        }
        private pVertexShader mVertexShader;
        public pPixelShader PixelShader
        {
            get
            {
                return mPixelShader;
            }
        }
        private pPixelShader mPixelShader;

    }
}
